package com.sdy.kzyy.web.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sdy.common.model.BizException;
import com.sdy.kzyy.biz.constants.RedisConstants;
import com.sdy.kzyy.biz.dto.UserDTO;
import com.sdy.kzyy.biz.service.UserService;
import com.sdy.kzyy.biz.vo.UserVo;
import com.sdy.kzyy.biz.model.PersonalInformation;
import com.sdy.kzyy.biz.service.PersonalInformationService;
import com.sdy.common.model.Response;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.sdy.mvc.controller.BaseController;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author zzq
 * @since 2020-03-03
 */
@Slf4j
@RestController
@RequestMapping("/user")
@Api(tags = "用户预约")
public class UserController extends BaseController {

    @Autowired
    private UserService userService;
    @Autowired
    private PersonalInformationService personalInformationService;
    @Autowired
    private RedisLockRegistry redisLockRegistry;
    @Value("${res.app.env.test:false}")
    private Boolean envTest;

    @PostMapping("/applyKz")
    @ApiOperation(value = "提交预约")
    public Response applyKz(HttpServletRequest request, @RequestBody UserDTO userDTO) throws BizException, InterruptedException {
        Integer userId = getUserId(request);
        if (null == userId) {
            return Response.error("请先登录");
        }
        userDTO.setUserId(userId);
        Lock lockCard = redisLockRegistry.obtain(RedisConstants.LOCK_APPLY_KZYY_CARD + userDTO.getCardid());
        if(!lockCard.tryLock(10, TimeUnit.SECONDS)) {
            throw new BizException("提交预约申请过于频繁，请规范操作。");
        }
        try {
            userService.applyKz(userDTO);
        }finally {
            lockCard.unlock();
        }
        return Response.success("预约成功");
    }

    @GetMapping("/data")
    @ApiOperation(value = "用户信息查询")
    public Response data(HttpServletRequest request) throws BizException {
        Integer userId = getUserId(request);
        if (null == userId) {
            return Response.error("");
        }
        List<PersonalInformation> personalInformationList = personalInformationService
                .list(new QueryWrapper<PersonalInformation>().eq("user_id", userId).orderByDesc("id"));
        return Response.success(personalInformationList);
    }

    @PostMapping("/applyKzTest")
    @ApiOperation(value = "提交预约,并发test")
    public Response applyKzTest(HttpServletRequest request, @RequestBody UserDTO userDTO) throws BizException, InterruptedException {
        if (!envTest) {
            return Response.error("请在测试环境使用。");
        }
        Lock lockCard = redisLockRegistry.obtain(RedisConstants.LOCK_APPLY_KZYY_CARD + userDTO.getCardid());
        if(!lockCard.tryLock(10, TimeUnit.SECONDS)) {
            throw new BizException("提交预约申请过于频繁，请规范操作。");
        }
        try {
            userService.applyKz(userDTO);
        }finally {
            lockCard.unlock();
        }
        return Response.success("预约成功");
    }

    @PostMapping("/giveOrCanleAuthority")
    @ApiOperation(value = "给药店管理者扫码功能授权")
    public Response giveOrCanleAuthority(HttpServletRequest request, @RequestBody UserVo userVo) {
        Integer userId = getUserId(request);
        return userService.authority(userId, userVo);
    }

}